#include "matrix.h"

Matrix::Matrix(int m, int n) : row(m), col(n)
{
    val = (row <= 0 || col <= 0) ? nullptr : new int[row * col];
    memset(val, 0, sizeof(val));
}

Matrix::Matrix(const Matrix &m) : row(m.row), col(m.col), val(nullptr)
{
    val = (row <= 0 || col <= 0) ? nullptr : new int[row * col];
    std::copy(m.val, m.val + (row * col), val);
}
Matrix::~Matrix()
{
    if (val != nullptr)
        delete[] val;
    val = nullptr;
}
Matrix &Matrix::operator=(const Matrix &m)
{
    Matrix tmp(m);
    std::swap(row, tmp.row);
    std::swap(col, tmp.col);
    std::swap(val, tmp.val);
    return *this;
}

Matrix &Matrix::operator+=(const Matrix &m)
{
    if (row != m.row || col != m.col)
        std::cerr << "Matrix does not match!" << std::endl;
    else
    {
        for (int i = 0; i < m.row * col; i++)
        {
            val[i] += m.val[i];
        }
    }
    return *this;
}
Matrix &Matrix::operator-=(const Matrix &m)
{
    if (row != m.row || col != m.col)
        std::cerr << "Matrix does not match!" << std::endl;
    else
    {
        for (int i = 0; i < m.row * col; i++)
        {
            val[i] -= m.val[i];
        }
    }
    return *this;
}
Matrix operator+(const Matrix &m, const Matrix &n)
{
    Matrix tmp = Matrix(m);
    tmp += n;
    return tmp;
}
Matrix operator-(const Matrix &m, const Matrix &n)
{
    Matrix tmp = Matrix(m);
    tmp -= n;
    return tmp;
}
std::istream &operator>>(std::istream &in, Matrix &m)
{
    for (int i = 0; i < m.row * m.col; i++)
    {
    loop:
        in >> m.val[i];
        if (in.fail())
        {
            in.clear();
            in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cerr << "Illegal input!" << std::endl;
            goto loop;
        }
    }
    return in;
}
std::ostream &operator<<(std::ostream &out, const Matrix &m)
{
    for (int i = 0; i < m.row * m.col; i++)
    {
        out << m.val[i] << (((i + 1) % m.col) ? ' ' : '\n');
    }
    return out;
}